package com.p2p.common.aop;

import com.p2p.common.annotation.Operator;
import com.p2p.common.interceptor.databind.DataBind;
import com.p2p.common.interceptor.databind.DataBindManager;
import com.p2p.common.interceptor.databind.DataBindType;
import com.p2p.common.utils.JSONUtil;
import com.p2p.user.po.UserOperationLog;
import com.p2p.user.service.UserOperationLogService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Allen on 2017/3/16.
 * 操作日志 AOP实现
 */
@Aspect
public class OperationAspect {
    private static final Logger logger = LoggerFactory.getLogger(OperationAspect.class);
    private static final DataBind<Long> USER_ID_BIND = DataBindManager.getInstance().getDataBind(DataBindType.USER_ID);

    @Autowired
    private UserOperationLogService userOperationLogService;

    @Around(value = "execution(* com.baomidou.mybatisplus.service..*(..)) || execution(* com.p2p.*.service..*.*(..))")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object object = proceedingJoinPoint.proceed();
        //用户第一次登陆和注册的时候，内存中不存在用户ID，会出现NULL，NULL跳过增加操作日志
        Long userId = USER_ID_BIND.get();
        if (userId == null) {
            return object;
        }
        //判断service接口注解是否有注解,如没有直接返回
        if (!proceedingJoinPoint.getTarget().getClass().getInterfaces()[0].isAnnotationPresent(Operator.class))
            return object;
        //获取service接口注解operatorClass,(标志是否是需要记录操作日志)
        boolean operatorClass = proceedingJoinPoint.getTarget().getClass().getInterfaces()[0].getAnnotation(Operator.class).operatorClass();
        String actionClass = proceedingJoinPoint.getTarget().getClass().getInterfaces()[0].getAnnotation(Operator.class).action();
        if (operatorClass) {
            Signature signature = proceedingJoinPoint.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            Method method = methodSignature.getMethod();
            List<Object> objectList = new ArrayList<Object>();
            //获取方法入参
            for (Object o : proceedingJoinPoint.getArgs()) {
                objectList.add(o);
            }
            UserOperationLog userOperationLog = new UserOperationLog();
            userOperationLog.setCreateTime(new Timestamp(System.currentTimeMillis()));
            userOperationLog.setContent(JSONUtil.beanToJson(objectList));
            //先判断方法是否有注解,有注解优先使用方法上面的日志描述
            if (method.isAnnotationPresent(Operator.class)) {
                String actionMethod = method.getAnnotation(Operator.class).action();
                userOperationLog.setAction(actionMethod);
            } else {
                String methodName = methodSignature.getMethod().getName();
                StringBuffer action = new StringBuffer();
                if (methodName.contains("select")) {
                    return object;
                }
                if (methodName.contains("insert")) {
                    action.append("插入").append(actionClass);
                }
                if (methodName.contains("update")) {
                    action.append("修改").append(actionClass);
                }
                if (methodName.contains("delete")) {
                    action.append("删除").append(actionClass);
                }
                userOperationLog.setAction(action.toString());
            }

            userOperationLog.setUserId(userId);
            userOperationLogService.insert(userOperationLog);
            //先判断方法是否有注解,有注解优先使用方法上面的日志描述
        }
        return object;
    }
}
